#include "AnimationSolver.h"
#include "tinyxml/tinyxml.h"
#include <iostream>

WSet::WSet()
{

}

WSet::~WSet()
{
	if (m_animations.size()>0)
	{
		for (int i=0;i<m_animations.size();i++)
		{
			delete m_animations[i];
		}
	}
}

AnimationSolver *AnimationSolver::Create()
{
	AnimationSolver *as=new AnimationSolver();
	if (as->Init())
	{
		return as;
	}
	delete as;
	return NULL;
}

AnimationSolver::AnimationSolver()
{


}

AnimationSolver::~AnimationSolver()
{
	if (m_Sets.size())
	{
		for (int i=0;i<m_Sets.size();i++)
		{
			delete m_Sets[i];
		}
	}
}


bool AnimationSolver::Init()
{
	//use tinyxml to open up and load the file that defines the animation solver
	TiXmlDocument loader("definition/animationsolver.xml");
	//traverse to generate the animations, sets and frames

    if (!loader.LoadFile())
    {
        std::cout << "cannot load animationsolver definition file" << std::endl;
        return false;
    }
	
	TiXmlElement *MapElement=loader.FirstChildElement("map");
	if (MapElement==NULL)
	{
        std::cout << "animation solver file invalid" << std::endl;
		return false;
	}
	TiXmlElement *SetElement=MapElement->FirstChildElement("set");
	while (SetElement!=NULL)
	{
		WSet *set=new WSet();
		set->m_index=atoi(SetElement->Attribute("index"));
		m_Sets.push_back(set);
		TiXmlElement *AnimationElement=SetElement->FirstChildElement("animation");
		while (AnimationElement!=NULL)
		{
			WAnimation *animation=new WAnimation();
			
			animation->m_index=atoi(AnimationElement->Attribute("index"));
			set->m_animations.push_back(animation);
			TiXmlElement *FrameElement=AnimationElement->FirstChildElement("frame");
			while (FrameElement!=NULL)
			{
				sf::Rect <int> rect;
				rect.left=atoi(FrameElement->Attribute("left"));
				rect.top=atoi(FrameElement->Attribute("top"));
				rect.width=atoi(FrameElement->Attribute("width"));
				rect.height=atoi(FrameElement->Attribute("height"));
				animation->m_frames.push_back(rect);
				FrameElement=FrameElement->NextSiblingElement("frame");
			}
			AnimationElement=AnimationElement->NextSiblingElement("animation");
		}
		SetElement=SetElement->NextSiblingElement("set");
	}
	
	Reorder();

	return true;
}

sf::Rect <int> AnimationSolver::getRect(int set, int animation, int *cframe, bool flip)
{
	if (animation>=m_Sets[set]->m_animations.size())
	{
		animation=0;
	}
	if (*cframe>=m_Sets[set]->m_animations[animation]->m_frames.size()-1)
	{
		*cframe=0;
	}
	else
	{
		*cframe=*cframe+1;
	}
	if (!flip)
	{
		return m_Sets[set]->m_animations[animation]->m_frames[*cframe]; 
	}
	else
	{
		sf::Rect <int> orect=m_Sets[set]->m_animations[animation]->m_frames[*cframe];
		sf::Rect <int> rect(orect.left+orect.width,orect.top,orect.width*-1,orect.height);
		return rect;
	}
}

void AnimationSolver::Reorder()
{

	for (int i=0;i<m_Sets.size();i++)
	{
		WSet *set=m_Sets[i];
		m_Sets[i]=NULL;
		m_Sets[set->m_index]=set;
		for (int i=0;i<set->m_animations.size();i++)
		{
			WAnimation *animation=set->m_animations[i];
			set->m_animations[i]=NULL;
			set->m_animations[i]=animation;
		}
	}
	//reorder the sets
	//reorder the frames
}